var uuidV4 = require('uuid/v4');
var Eventproxy = require('eventproxy');
var logger = require('../common/logger');
var models = require('../models');
var tools = require('../common/tools');
var config = require('config-lite');
var Sequelize = require('sequelize');
var qr = require('qr-image');

exports.newStaff = function newStaff(req, res, next) {
  var ep = new Eventproxy();
  ep.fail(next);

  var user = req.user;
  var data = req.body;

  var staffId = req.params.uuid;

  ep.all('missing', function (attrs) {
    if (attrs.length) {
      return res.send_data({
        code: 400,
        message: '缺少字段' + attrs
      });
    }
  });
  var missingAttrs;
  if (data.type * 1) {
    missingAttrs = tools.checkMissingAttr(data, ['name', 'name_en', 'sex', 'idtype', 'idno', 'organization', 'organization_en', 'position_uuid', 'groups', 'avatar', 'forbidden_areas', 'allow_areas']);
  } else {
    missingAttrs = tools.checkMissingAttr(data, ['belongto_area_uuid', 'forbidden_areas', 'allow_areas']);
  }
  if (missingAttrs.length) {
    return ep.emit('missing', missingAttrs);
  }

  data.sex = data.sex || 1;
  data.idtype = data.idtype || 1;
  data.position_uuid = data.position_uuid || null;
  data.name = data.name ? data.name.trim() : data.name;
  data.name_en = data.name_en ? data.name_en.trim() : data.name_en;
  data.idno += '';
  data.idno = data.idno.trim();
  data.organization = data.organization ? data.organization.trim() : data.organization;
  data.organization_en = data.organization_en ? data.organization_en.trim() : data.organization_en;
  var forbidden_areas = data.forbidden_areas;
  var allow_areas = data.allow_areas;

  var sameVal = allow_areas.filter(function(v){ return forbidden_areas.indexOf(v) > -1 });
  if (sameVal.length) {
    return res.send_data({
      code: 400,
      message: '限行区域和可通行区域存在相同值'
    });
  }

  data.event_uuid = user.event_uuid;

  ep.all('getEvent', 'createStaff', 'createStaffGroups', 'createForbiddens', 'createAllows', function(event, staffData) {
    if (staffData) { // 新增
      var _staff = staffData.toJSON();
      var code = tools.encrypt(_staff.uuid, config.admin_secret);
      _staff.qrcode = code;
      _staff.qrcode_link = '/staffs/' + _staff.uuid + '/qrcode';
      if (event) {
        _staff.no = event.no;
      }
    }
    return res.send_data({
      entities: _staff
    });
  });

  if (staffId) { // 编辑
    ep.emit('getEvent', null);

    var staffGroups = data.groups.map(function(item) {
      return {
        staff_uuid: staffId,
        group_uuid: item
      };
    });
  
    models.staff.update(data, {
      where: {
        uuid: staffId
      }
    }).then(function(returnData) {
      ep.emit('createStaff');
    });

    models.staff_area.destroy({
      where: {
        staff_uuid: staffId
      }
    }).then(function() {
      var forbiddens = forbidden_areas.map(function(area) {
        return {
          staff_uuid: staffId,
          area_uuid: area,
          type: 2
        };
      });
      models.staff_area.bulkCreate(forbiddens).then(function() {
        ep.emit('createForbiddens');
      });
  
      var allows = allow_areas.map(function(area) {
        return {
          staff_uuid: staffId,
          area_uuid: area,
          type: 1
        };
      });
      models.staff_area.bulkCreate(allows).then(function() {
        ep.emit('createAllows');
      });
    });

    models.staff_group.destroy({
      where: {
        staff_uuid: staffId
      }
    }).then(function() {
      models.staff_group.bulkCreate(staffGroups).then(function() {
        ep.emit('createStaffGroups');
      });
    });
  } else {
    models.event.findOne({
      where: {
        uuid: data.event_uuid
      }
    }).then(function(event) {
      return event.increment('no', {by: 1});
    }).then(function(event) {
      event.reload().then(function() {
        ep.emit('getEvent', event);

        data.no = event.no;
        models.staff.create(data).then(function(returnStaff) {
          var staffId = returnStaff.uuid;
    
          var forbiddens = forbidden_areas.map(function(area) {
            return {
              staff_uuid: staffId,
              area_uuid: area,
              type: 2
            };
          });
          models.staff_area.bulkCreate(forbiddens).then(function() {
            ep.emit('createForbiddens');
          });
      
          var allows = allow_areas.map(function(area) {
            return {
              staff_uuid: staffId,
              area_uuid: area,
              type: 1
            };
          });
          models.staff_area.bulkCreate(allows).then(function() {
            ep.emit('createAllows');
          });
      
          var staffGroups = data.groups.map(function(item) {
            return {
              staff_uuid: staffId,
              group_uuid: item
            };
          });
          models.staff_group.bulkCreate(staffGroups).then(function() {
            ep.emit('createStaffGroups');
          });
          ep.emit('createStaff', returnStaff);
        });
      });
    });
  }
};

exports.getStaffs = function getStaffs(req, res, next) {
  var reqQuery = req.query;
  var page = parseInt(reqQuery.page, 10) || 1;
  page = page > 0 ? page : 1;
  var limit = models.staff.pageLimit(Number(reqQuery.limit));
  var offset = models.staff.pageOffset(page, limit);

  var exported = reqQuery.exported || 'all';
  var keyword = reqQuery.s;
  var filterGroup = reqQuery.group_uuid || 'all';

  var condition = {
    offset: offset,
    limit: limit,
    where: {
      type: 1
    },
    include: [{
      model: models.group,
      through: true
    }, {
      model: models.position
    }, {
      model: models.area,
      through: true
    }, {
      as: 'belongto_area',
      model: models.area
    }]
  };

  if (exported !== 'all') {
    condition.where.status = exported;
  }

  if (filterGroup !== 'all') {
    condition.include = [{
      model: models.group,
      where: {
        uuid: filterGroup
      },
      through: true
    }, {
      model: models.position
    }];
  }

  if (keyword) {
    // https://github.com/sequelize/sequelize/issues/2077#issuecomment-58616291
    // https://stackoverflow.com/questions/32752840/sequelize-concat-fields-in-where-like-clause
    // https://my.oschina.net/BearCatYN/blog/316499
    var keywords = keyword.split(' ');
    if (keywords.length >= 1) {
      var queryKeys = [];
      for (var i = 0, l = keywords.length; i < l; i++) {
        queryKeys.push(Sequelize.where(Sequelize.fn('CONCAT_WS', '',
        Sequelize.col('`staff`.`name`'),
        Sequelize.col('`staff`.`name_en`')), {
          like: '%' + keywords[i] + '%'
        }));
      }
    }
    condition.where.$and = queryKeys;
  }

  var user = req.user;
  if (user.event_uuid) {
    condition.where.event_uuid = user.event_uuid;
  }

  models.staff.findAndCountAll(condition).then(function(returnStaffs) {
    return res.send_data({
      entities: returnStaffs.rows,
      total_pages: models.staff.totalPages(returnStaffs.count, limit),
      current_page: page
    })
  });
};

exports.getStaffByUUID = function getStaffByUUID(req, res) {
  var staffUUID = req.params.uuid;

  models.staff.findOne({
    where: {
      uuid: staffUUID
    },
    include: [{
      model: models.group,
      through: true
    }, {
      model: models.area,
      through: true
    }, {
      as: 'belongto_area',
      model: models.area
    }]
  }).then(function(returnStaff) {
    var _staff = returnStaff.toJSON();
    var code = tools.encrypt(_staff.uuid, config.admin_secret);
    _staff.qrcode = code;
    _staff.qrcode_link = '/staffs/' + staffUUID + '/qrcode';
    return res.send_data({
      entities: _staff
    });
  });
};

// 验证人员身份
// exports.vefiryStaff = function vefiryStaff(req, res, next) {
//   var ep = new Eventproxy();
//   ep.fail(next);

//   var staffUUID = req.params.uuid;

//   var user = req.user;
//   var data = req.body;

//   ep.all('missing', function (attrs) {
//     if (attrs.length) {
//       return res.send_data({
//         code: 400,
//         message: '缺少字段' + attrs
//       });
//     }
//   });
//   var missingAttrs = tools.checkMissingAttr(data, ['area_uuid']);
//   if (missingAttrs.length) {
//     return ep.emit('missing', missingAttrs);
//   }

//   ep.all('getStaff', 'getPositionAreas', function(staff, positionAreas) {
//     var accessAreas = [], forbiddenAreas = [];
//     positionAreas.forEach(function(area) {
//       if (area.type === 1) {
//         accessAreas.push(area.area_uuid);
//       } else {
//         forbiddenAreas.push(area.area_uuid);
//       }
//     });
//     console.log(accessAreas)
//     console.log(forbiddenAreas)
//     return res.send_data({
//       entities: positionAreas
//     });
//   });

//   ep.on('getStaff', function(staff) {
//     models.position_area.findAll({
//       where: {
//         position_uuid: staff.position_uuid
//       }
//     }).then(function(returnData) {
//       ep.emit('getPositionAreas', returnData);
//     });
//     var groups = staff.groups.map(function(item){
//       return item.uuid;
//     });
//     console.log(groups)
//   });

//   models.staff.findOne({
//     where: {
//       uuid: staffUUID
//     },
//     include: [{
//       model: models.group,
//       through: true
//     }]
//   }).then(function(returnStaff) {
//     ep.emit('getStaff', returnStaff);
//   });
// }; 

exports.vefiryStaff = function vefiryStaff(req, res, next) {
  var ep = new Eventproxy();
  ep.fail(next);

  var code = req.params.uuid;
  var trueId, returnData;
  trueId = tools.decrypt(code, config.admin_secret);
  if (trueId) {
    models.staff.findOne({
      where: {
        uuid: trueId
      },
      include: [{
        model: models.group,
        through: true,
        include: [{
          model: models.area,
          through: true,
          include: [{
            as: 'belongto_area',
            model: models.area
          }]
        }]
      }, {
        model: models.area,
        through: true,
        include: [{
          as: 'belongto_area',
          model: models.area
        }]
      }, {
        as: 'belongto_area',
        model: models.area
      }]
    }).then(function(returnStaff) {
      var _staff = returnStaff.toJSON();
      var code = tools.encrypt(_staff.uuid, config.admin_secret);
      _staff.qrcode = code;
      return res.send_data({
        entities: _staff
      });
    });
  } else {
    returnData = {
      code: 400,
      message: 'wrong code'
    };
    return res.send_data(returnData);
  }
};

exports.exportStaff = function exportStaff(req, res) {
  var staffId = req.params.uuid;

  models.staff.update({
    status: 1
  }, {
    where: {
      uuid: staffId
    }
  }).then(function() {
    return res.send_data();
  });
};

exports.delStaff = function delStaff(req, res) {
  var data = req.body;

  var staffId = req.params.uuid;

  models.staff.destroy({
    where: {
      uuid: staffId
    }
  }).then(function() {
    return res.send_data();
  });

  models.staff_group.destroy({
    where: {
      staff_uuid: staffId
    }
  }).then(function() {
    logger.info('Staff: ' + staffId + ' 相关的staff_group信息已删除！');
  });
};

exports.batchUpdateStaff = function batchUpdateStaff(req, res, next) {
  var ep = new Eventproxy();
  ep.fail(next);

  var user = req.user;
  var data = req.body;

  ep.all('missing', function (attrs) {
    if (attrs.length) {
      return res.send_data({
        code: 400,
        message: '缺少字段' + attrs
      });
    }
  });
  var missingAttrs = tools.checkMissingAttr(data, ['staff_uuids', 'group_uuids']);
  if (missingAttrs.length) {
    return ep.emit('missing', missingAttrs);
  }

  var staff_uuids = data.staff_uuids;
  var group_uuids = data.group_uuids;

  var bulkData = [];
  staff_uuids.forEach(function(staff_uuid) {
    group_uuids.forEach(function(group_uuid) {
      bulkData.push({
        staff_uuid: staff_uuid,
        group_uuid: group_uuid
      });
    });
  });

  models.staff_group.destroy({
    where: {
      staff_uuid: {
        $in: staff_uuids
      }
    }
  }).then(function() {
    models.staff_group.bulkCreate(bulkData).then(function() {
      return res.send_data();
    });
  })
};

exports.qrcodeLink = function qrcodeLink(req, res) {
  var uuidText = tools.encrypt(req.params.uuid, config.admin_secret);
  var code = qr.image(uuidText, { type: 'png', margin: 1 });
  res.setHeader('Content-type', 'image/png');
  code.pipe(res);
};
